package com.hsgene.order.controller.invoice;

import com.hsgene.common.util.exception.ErrorCode;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.order.domain.billing.constant.BillingApplyErrorCode;
import com.hsgene.order.domain.billing.constant.InvoiceStatus;
import com.hsgene.order.domain.billing.dto.*;
import com.hsgene.order.exception.ObjectAttributeInfoEnum;
import com.hsgene.order.exception.OrderErrorCode;
import com.hsgene.order.service.InvoiceOpenService;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 开票管理
 *
 * @author wxf
 * @date 2018/11/2 11:58
 **/
@RestController
@RequestMapping("/v1.0/genetic/testing/orders/billing")
public class InvoiceOpenController {
    /**
     * Log
     */
    private static Logger LOGGER = LogManager.getLogger(InvoiceOpenController.class);

    @Resource
    private InvoiceOpenService invoiceOpenService;

    /**
     * 获取发票列表
     *
     * @param con 参数
     * @return
     */
    @GetMapping
    public ApiResult<List<BillingApplyListInfoDto>> queryApplyBilling(BillingApplyConditionDto con) {
        try {
            Integer page = con.getPage();
            Integer size = con.getSize();
            if (page == null || size == null || page == 0) {
                return ApiResult.fail(BillingApplyErrorCode.PAGE_SIZE_IS_NOT_NULL);
            }
            if (page < 0 || size < 0) {
                return ApiResult.fail(BillingApplyErrorCode.PAGE_SIZE_IS_NOT_LESS_ZEERO);
            }
            if (StringUtils.isEmpty(con.getOrderType())) {
                con.setOrderType("asc");
            }
            con.setPage((page - 1) * size);
            BillingApplySumInfoDto result = invoiceOpenService.queryApplyBilling(con);
            return new ApiResult(200, "success", "查询成功", result);
        } catch (Exception e) {
            LOGGER.error("query apply billing is error...", e);
            return ApiResult.fail(BillingApplyErrorCode.QUERY_BILLING_APPLY_IS_ERROR);
        }
    }

    /**
     * 获取发票信息
     *
     * @param orderId 发票id
     * @return
     */
    @GetMapping("invoice/{order_id}")
    public ApiResult<OrderInvoiceInfoDto> getInvoiceInfo(@PathVariable("order_id") String orderId) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(BillingApplyErrorCode.INVOICE_ID_IS_NOT_NULL);
            }
            OrderInvoiceInfoDto invoiceInfoDto = invoiceOpenService.getInvoiceInfo(orderId);
            if (invoiceInfoDto == null) {
                LOGGER.error("invoice info is not exists...");
                return ApiResult.fail(BillingApplyErrorCode.INVOICE_IINFO_IS_NOT_EXISTS);
            }
            return new ApiResult(200, "success", "获取发票信息成功", invoiceInfoDto);
        } catch (Exception e) {
            LOGGER.error("get invoice info is error...", e);
            return ApiResult.fail(BillingApplyErrorCode.GET_INVOICE_IS_ERROR);
        }
    }

    /**
     * 修改发票
     *
     * @return infoDto修改信息
     */
    @PutMapping
    public ApiResult<Boolean> updateInvoice(@RequestBody OrderInvoiceInfoDto infoDto) {
        try {
            //校验参数
            ErrorCode errorCode = checkUpdateParams(infoDto);
            if (errorCode != null) {
                return ApiResult.fail(errorCode);
            }
            //更新发票
            Boolean flag = invoiceOpenService.updateInvoice(infoDto);
            if (flag) {
                return new ApiResult(200, "success", "修改发票成功", flag);
            }
            return ApiResult.fail(BillingApplyErrorCode.UPDATE_INVOICE_IS_FAILED);
        } catch (Exception e) {
            LOGGER.error("update invoice is error...", e);
            return ApiResult.fail(BillingApplyErrorCode.UPDATE_INVOICE_IS_ERROR);
        }
    }

    /**
     * 获取申请开票详情
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping("{order_id}")
    public ApiResult<OrderApplyBillingInfoDto> getApplyBillingDetails(@PathVariable("order_id") String orderId) {
        if (StringUtils.isEmpty(orderId)) {
            return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
        }
        //校验订单发票信息是否完整
        Boolean flag = invoiceOpenService.getOrderInvoice(orderId);
        if (!flag) {
            return ApiResult.fail(BillingApplyErrorCode.INVOICE_IS_NOT_FINISHED);
        }
        OrderApplyBillingInfoDto billingInfoDto = invoiceOpenService.getApplyBillingDetails(orderId);
        if (billingInfoDto == null) {
            return ApiResult.fail(OrderErrorCode.ORDER_EXCEPTION);
        }
        return new ApiResult(200, "success", "获取开票信息成功", billingInfoDto);
    }

    /**
     * 申请开票
     *
     * @param orderId
     * @return
     */
    @PostMapping("{order_id}/apply")
    public ApiResult applyBilling(@PathVariable("order_id") String orderId) {
        try {
            if (StringUtils.isEmpty(orderId)) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            return invoiceOpenService.applyBilling(orderId);
        } catch (Exception e) {
            LOGGER.error("applyBilling is error...", e);
            return ApiResult.fail(BillingApplyErrorCode.INVOICE_APPLY_IS_ERROR);
        }
    }

    /**
     * 合并发票
     *
     * @param mergeInfoDto
     * @return
     */
    @PostMapping("merge")
    public ApiResult applyMergeBilling(@RequestBody OrderBillingMergeInfoDto mergeInfoDto) {
        try {
            if (mergeInfoDto == null || mergeInfoDto.getOrderIds() == null || mergeInfoDto.getOrderIds().isEmpty()) {
                return ApiResult.fail(OrderErrorCode.ORDER_ID_IS_NOT_NULL);
            }
            List<String> orderIds = mergeInfoDto.getOrderIds();
            //校验订单发票信息是否完整
            //TODO 待优化
            for (String orderId : orderIds) {
                Boolean flag = invoiceOpenService.getOrderInvoice(orderId);
                if (!flag) {
                    return ApiResult.fail(BillingApplyErrorCode.INVOICE_IS_NOT_FINISHED);
                }
            }
            //校验发票是否是同一个人的
            List<OrderPersonBillingDto> check = invoiceOpenService.checkOrderIsOneSelf(orderIds);
            if (check == null || check.isEmpty()) {
                return ApiResult.fail(OrderErrorCode.ORDER_NOT_EXISTED);
            }
            if (check.size() > 1) {
                return ApiResult.fail(BillingApplyErrorCode.INVOICE_IS_NOT_ONESELT);
            }
            //合并发票
            return invoiceOpenService.mergeApplyBilling(orderIds);
        } catch (Exception e) {
            LOGGER.error("applyBilling is error...", e);
            return ApiResult.fail(BillingApplyErrorCode.INVOICE_APPLY_IS_ERROR);
        }
    }

    private ErrorCode checkUpdateParams(OrderInvoiceInfoDto infoDto) {
        if (infoDto.getInvoiceType() == null) {
            return BillingApplyErrorCode.INVOICE_TYPE_IS_NOT_NULL;
        }
        if (infoDto.getInvoiceStatus() == null) {
            return BillingApplyErrorCode.INVOICE_STATUS_IS_NOT_NULL;
        }
        //重开发票，发票ID不能为空,重开说明不能为空
        if (infoDto.getInvoiceStatus() == InvoiceStatus.SIX.getCode() && StringUtils.isEmpty(infoDto
                .getReopenExplanation())) {
            return BillingApplyErrorCode.REOPEN_EXPLANATION_IS_NOT_NULL;
        }
        if (StringUtils.isEmpty(infoDto.getInvoiceName())) {
            return BillingApplyErrorCode.INVOICE_NAME_IS_NOT_NULL;
        }
        //企业
        if (infoDto.getInvoiceType() == 1) {
            //企业凭证
            List<String> voucher = infoDto.getEnterpriseSealVoucher();
            if (voucher == null || voucher.isEmpty() || voucher.size() > 1) {
                return BillingApplyErrorCode.INVOICE_VOUCHER_IS_NOT_NULL;
            }
            //纳税号
            if (StringUtils.isEmpty(infoDto.getTaxesNo())) {
                return ObjectAttributeInfoEnum.taxesNo;
            }
        }
        return null;
    }

}
